package com.zjjt.dc.tools.upload.file.pool;

import com.zjjt.dc.tools.upload.file.config.AliOssBucketConfig;
import com.zjjt.dc.tools.upload.file.config.UploadFileConfig;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

public class UploadThreadPoolManager {

    private static final AtomicLong lastTaskTime = new AtomicLong(System.currentTimeMillis());
    // 守护线程，用于监控线程池活动情况
    private static final Thread monitorThread;
    private static volatile ExecutorService executorService = Executors.newFixedThreadPool(UploadFileConfig.getInstance().getPoolSize());

    static {
        // 启动监控线程
        monitorThread = new Thread(new MonitorRunnable(), "ExecutorPoolMonitor");
        monitorThread.setDaemon(true);
        monitorThread.start();

        // 注册关闭钩子，确保程序退出时关闭线程池
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            shutdownExecutorService();
        }));
    }

    // 防止实例化
    private UploadThreadPoolManager() {
    }

    public static ExecutorService getExecutorService() {
        // 提交任务时更新最后活动时间
        lastTaskTime.set(System.currentTimeMillis());
        return executorService;
    }

    /**
     * 关闭线程池
     */
    private static void shutdownExecutorService() {
        ExecutorService service = executorService;
        if (service != null && !service.isShutdown()) {
            try {
                service.shutdown();
                if (!service.awaitTermination(60, TimeUnit.SECONDS)) {
                    service.shutdownNow();
                    // 再次等待终止
                    if (!service.awaitTermination(60, TimeUnit.SECONDS)) {
                        System.err.println("线程池未能正常关闭");
                    }
                }
            } catch (InterruptedException e) {
                service.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }

    /**
     * 重新初始化线程池
     */
    private static synchronized void reinitializeExecutorService() {
        ExecutorService oldService = executorService;
        if (oldService != null && (oldService.isShutdown() || oldService.isTerminated())) {
            executorService = Executors.newFixedThreadPool(UploadFileConfig.getInstance().getPoolSize());
        }
    }

    /**
     * 监控线程池活动的可运行任务
     */
    private static class MonitorRunnable implements Runnable {
        private static final long CHECK_INTERVAL = UploadFileConfig.getInstance().getCheckInterval() * 1000; // 1分钟检查一次
        private static final long IDLE_THRESHOLD = UploadFileConfig.getInstance().getTimeout() * 1000; // 10分钟空闲阈值

        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    long currentTime = System.currentTimeMillis();
                    long lastTime = lastTaskTime.get();

                    // 如果超过10分钟没有新任务，则关闭线程池
                    if (currentTime - lastTime > IDLE_THRESHOLD) {
                        // 检查线程池是否真的空闲（没有活跃任务）
                        boolean isIdle = true;
                        if (executorService instanceof ThreadPoolExecutor) {
                            ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService;
                            int activeCount = threadPoolExecutor.getActiveCount();
                            int queueSize = threadPoolExecutor.getQueue().size();

                            // 只有在线程池中没有活跃线程且队列中没有等待任务时才认为是空闲的
                            isIdle = (activeCount == 0 && queueSize == 0);
                        }

                        if (isIdle) {
                            System.out.println("线程池空闲超过10分钟且无活跃任务，正在关闭线程池...");
                            shutdownExecutorService();
                            break;
                        }
                    }

                    Thread.sleep(CHECK_INTERVAL);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                } catch (Exception e) {
                    // 记录异常但继续监控
                    System.err.println("监控线程出现异常: " + e.getMessage());
                }
            }
        }
    }
}
